package com.css.fxfzypg.modules.system.service;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.constants.FxfzConstants;
import com.css.fxfzypg.constants.SysUserRoleTypeEnum;
import com.css.fxfzypg.modules.system.model.entity.SysUserRole;
import com.css.fxfzypg.util.CreateGson;
import com.css.fxfzypg.zcpt.sys.entity.SUser;
import com.css.fxfzypg.zcpt.sys.service.SUserService;
import com.css.fxfzypg.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserCacheService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SUserService sUserService;

    @Autowired
    private SysRoleService sysRoleService;
    public final static String SYS_USER_ROLES = "ypg:sys:user_roles:";
    public final static String SYS_USER_INFO_KEY = "ypg:sys:details:user";

    public String getUsername(String userId) {
        SUser user = this.getUser(userId);
        if (user == null) {
            return "未知用户";
        } else {
            return user.getUserName();
        }
    }

    /**
     * 获取用户信息
     * <p>
     * 用户id
     * 先走缓存，缓存没有调接口，然后存储缓存，配置缓存60分钟过期
     */
    public SUser getUser(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        String userJson = sUserService.getSUser(userId);
        if (StringUtils.isBlank(userJson)) {
            return null;
        }
        return CreateGson.createGson().fromJson(userJson, SUser.class);
    }

    /**
     * 获取用户信息
     * <p>
     * 用户id
     * 先走缓存，缓存没有调接口，然后存储缓存，配置缓存60分钟过期
     */
    public SUser getUserFromCache(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        String redisKey = SYS_USER_INFO_KEY;
        ValueOperations<String, SUser> valueOperations = redisTemplate.opsForValue();
        SUser sUser = valueOperations.get(redisKey + userId);
        if (sUser != null) {
            return sUser;
        }
        String userJson = sUserService.getSUser(userId);
        if (StringUtils.isBlank(userJson)) {
            return null;
        }
        sUser = CreateGson.createGson().fromJson(userJson, SUser.class);
        valueOperations.set(redisKey + userId, sUser);
//        redisTemplate.expire(redisKey + userId, 60, TimeUnit.MINUTES);
        redisTemplate.expire(redisKey + userId, 5, TimeUnit.MINUTES);
        return sUser;
    }

    public List<SUser> getUserCacheList() {
        Set<String> keys = redisTemplate.keys(SYS_USER_INFO_KEY + "*");
        ValueOperations<String, SUser> valueOperations = redisTemplate.opsForValue();
        return valueOperations.multiGet(keys);
    }

    /**
     * 查询用户权限信息
     *
     * @param userId
     * @return
     */
    public List<SysUserRole> getRole(String userId) {
        try {
            ValueOperations<String, List<SysUserRole>> ops = redisTemplate.opsForValue();
            List<SysUserRole> sysUserRoles = ops.get(SYS_USER_ROLES + userId);
            if (CollectionUtils.isEmpty(sysUserRoles)) {
                String roleStr = sysRoleService.getRoleByUserId(userId);
                if (StringUtils.isNotBlank(roleStr)) {
                    sysUserRoles = JSONObject.parseArray(roleStr, SysUserRole.class);
                }
                if (sysUserRoles == null) {
                    return null;
                }
                ops.set(SYS_USER_ROLES + userId, sysUserRoles);
                redisTemplate.expire(SYS_USER_ROLES + userId, 60, TimeUnit.MINUTES);
            }
            return sysUserRoles;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 每过1分钟同步1次用户角色信息
     */
    @Scheduled(cron = "0 */1 * * * ?")
    public void syncUserRole() {
        try {
            ValueOperations<String, List<SysUserRole>> ops = redisTemplate.opsForValue();
            Set<String> keys = redisTemplate.keys(SYS_USER_ROLES + "*");
            if (keys != null) {
                List<String> ids = keys.stream().map(o -> StringUtils.remove(o, SYS_USER_ROLES)).collect(Collectors.toList());
                for (String userId : ids) {
                    List<SysUserRole> sysUserRoles = ops.get(SYS_USER_ROLES + userId);
                    if (sysUserRoles == null) {
                        continue;
                    }
                    String roleStr = sysRoleService.getRoleByUserId(userId);
                    if (StringUtils.isNotBlank(roleStr)) {
                        try {
                            List<SysUserRole> newSysUserRoles = JSONObject.parseArray(roleStr, SysUserRole.class);
                            if (!CollectionUtils.isEmpty(newSysUserRoles)) {
                                if (isUpdate(sysUserRoles, newSysUserRoles)) {
                                    redisTemplate.delete(SYS_USER_ROLES + userId);
                                }
                            }
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 判断base是否更新了角色信息
     *
     * @param source
     * @param target
     * @return
     */
    private static boolean isUpdate(List<SysUserRole> source, List<SysUserRole> target) {
        List<String> sourceRoleCodeList = source.stream().map(SysUserRole::getRoleCode).collect(Collectors.toList());
        for (SysUserRole sysUserRole : target) {
            if (!sourceRoleCodeList.contains(sysUserRole.getRoleCode())) {
                return true;
            }
        }
        return false;
    }

    public SysUserRoleTypeEnum getUserRoleType(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        List<SysUserRole> role = this.getRole(userId);
        if (!CollectionUtils.isEmpty(role)) {
            boolean flag = false;
            for (SysUserRole sysUserRole : role) {
                if (sysUserRole.getRoleCode().equals(FxfzConstants.YPG_COUN_GL_ROLE) || sysUserRole.getRoleCode().equals(FxfzConstants.YPG_COUN_YW_ROLE) || sysUserRole.getRoleCode().equals("ypg_test_role")) {
                    return SysUserRoleTypeEnum.DATA_ROLES_COUNTRY;
                }
                if (sysUserRole.getRoleCode().equals(FxfzConstants.YPG_PRI_GL_ROLE) || sysUserRole.getRoleCode().equals(FxfzConstants.YPG_PRI_YW_ROLE)) {
                    flag = true;
                }
            }
            if (flag) {
                return SysUserRoleTypeEnum.DATA_ROLES_PROVINCE;
            }
        }
        return SysUserRoleTypeEnum.DATA_ROLES_OTHER;
    }
}
